﻿using ActiproSoftware.Windows;
using ActiproSoftware.Windows.Controls.Docking;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Data;
using FileTranslator;
using System.Activities.Presentation.PropertyEditing;


namespace UnionPay
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        //当前正在处理的数据集合
        DataContainer curContainer; 

        public MainWindow()
        {
            LoaderHelper.LoadFilesAndSetConstraints();
            curContainer = LoaderHelper.GetFmtData();

            InitializeComponent();
            FullScreenManager.RepairWpfWindowFullScreenBehavior(this);
            // 最大化窗口
            this.WindowState = System.Windows.WindowState.Maximized;
        }

        #region Main window related functions
        private void OnMainWindowLoaded(object sender, RoutedEventArgs e)
        {

        }

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            this.DragMove();
        }

        private void closeButton_Click(object sender, RoutedEventArgs e)
        {
            this.Close();
        }

        private void maxButton_Click(object sender, RoutedEventArgs e)
        {
            if (WindowState == WindowState.Normal)
                WindowState = WindowState.Maximized;
            else
                WindowState = WindowState.Normal;  
        }

        private void mniButton_Click(object sender, RoutedEventArgs e)
        {
            this.WindowState = WindowState.Minimized;
        }

        private void menuButton_Click(object sender, RoutedEventArgs e)
        {
            Menu.IsOpen = true;
        }
        #endregion

        #region Search Text
        private void OnSearchButtonClick(object sender, RoutedEventArgs e)
        {
            
        }
        #endregion

        #region TreeView Related Functions
        int curDataViewIndex = 0;
        private void OnTreeViewLoaded(object sender, RoutedEventArgs e)
        {
            // Expand all root TreeView nodes on load
            foreach (object item in this.FileListTreeView.Items)
            {
                TreeViewItem container = (TreeViewItem)this.FileListTreeView.ItemContainerGenerator.ContainerFromItem(item);
                if (null != container)
                    container.IsExpanded = true;
            }
        }

        List<TreeViewItemWithIcons> treeViewItems = new List<TreeViewItemWithIcons>();
        private void OnTreeViewInitialized(object sender, EventArgs e)
        {
            treeViewItems.Clear();

            // 初始化工作
            string folderPath = @"\skin\ico\ico_folder16.png";
            string filePath = @"\skin\ico\ico_file16.png";
            string checkMarkPath = @"\skin\ico\ico_check.png";

            ImageSource folderIcon = new BitmapImage(new Uri(folderPath, UriKind.Relative));
            ImageSource fileIcon = new BitmapImage(new Uri(filePath, UriKind.Relative));
            ImageSource fileIconAfter = new BitmapImage(new Uri(checkMarkPath, UriKind.Relative));

            // TODO:如果需要有多个root，可以采用List<DataContainer>的方式
            int index = 0;
            TreeViewItemWithIcons root = new TreeViewItemWithIcons();
            root.HeaderText = curContainer.Category;
            root.IconBefore = folderIcon;
            root.IndexInTreeView = index++;
            
            foreach (DataTableWrapper dtw in curContainer.GetDataTableWrappers())
            {
                TreeViewItemWithIcons node = new TreeViewItemWithIcons();
                node.HeaderText = dtw.InnerTable[0][curContainer.DescriptionColumn].ToString();
                node.IconBefore = fileIcon;
                node.IconAfter = fileIconAfter;
                node.IndexInTreeView = index++;

                root.Items.Add(node);
                treeViewItems.Add(node);
            }

            this.FileListTreeView.Items.Add(root);
        }

        private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            TreeView tv = FileListTreeView;
            if (tv != null && tv.SelectedItem != null)
            {
                TreeViewItemWithIcons node = (TreeViewItemWithIcons)tv.SelectedItem;

                // 叶子节点
                curDataViewIndex = node.IndexInTreeView;

                // 通知DataGrid修改数据源
                DataTableWrapper dtw = curContainer.GetDataTableWrapper(curDataViewIndex);
                if (dtw == null)
                {
                    return;
                }
                ResetDataGridDataContext(dtw.InnerTable);
            }
        }

        private void TreeViewInsertNewItem(object sender, RoutedEventArgs e)
        {
        }

        private void TreeViewDeleteItem(object sender, RoutedEventArgs e)
        {
        }
        #endregion

        #region File Search 
        private void OnFileSearchLoaded(object sender, RoutedEventArgs e)
        {
            ToolWindow tw = sender as ToolWindow;
            tw.Activate(true);
        }
        #endregion

        #region Data Grid 
        // DataGrid 加载
        private void OnDataGridLoaded(object sender, EventArgs e)
        {
            ResetDataGridDataContext(curContainer.GetDataTableWrapper(0).InnerTable);
        }

        private void ResetDataGridDataContext(object o)
        {
            dataGrid.IsReadOnly = !(bool)cbTableEdiable.IsChecked;
            //dataGrid.DataContext = o;
            Binding binding = new Binding();
            binding.Source = o;
            binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            dataGrid.SetBinding(DataGrid.DataContextProperty, binding);
        }

        #region Selction change
        // 当前用户选择了DataGrid中的哪一行
        int currentDataGridSelectionIndex = -1;
        private void OnDataGridSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            currentDataGridSelectionIndex = dataGrid.SelectedIndex;
            NotifyPropertyGridSelectedChanged(currentDataGridSelectionIndex);
        }
        #endregion

        #region row swaping for DataGrid
        private void OnDataGridRightMouseUp(object sender, MouseButtonEventArgs e)
        {
            // 如果用户已经标记了两行，则它需要做的事情是“交换”
            if (dataGrid.SelectedItems.Count != 2)
            {
                // 右键所在的行标记为选中行
                int indexInTable = -1;
                object item = GetElementFromPoint(
                    (ItemsControl)sender, e.GetPosition((ItemsControl)sender), ref indexInTable);

                if (item != null)
                {
                    dataGrid.SelectedItem = dataGrid.Items[indexInTable];
                }
            }
            // 将选中行高亮
            dataGrid.Focus();

            AreButtonsAvailable();
        }

        // 仅仅根据鼠标位置找到空间内某行
        private object GetElementFromPoint(ItemsControl itemsControl, Point point, ref int indexInTable)
        {
            UIElement element = itemsControl.InputHitTest(point) as UIElement;
            while (element != null)
            {
                if (element == itemsControl)
                    return null;
                object item = itemsControl.ItemContainerGenerator.ItemFromContainer(element);
                if (!item.Equals(DependencyProperty.UnsetValue))
                {
                    indexInTable = itemsControl.ItemContainerGenerator.IndexFromContainer(element);
                    return item;
                }
                element = (UIElement)VisualTreeHelper.GetParent(element);
            }
            return null;
        }
        #endregion

        #region Row Edit
        private void OnGridDataCurCellChanged(object sender, EventArgs e)
        {
            if (currentDataGridSelectionIndex != -1)
            {
                DataRowView drv = (DataRowView)(dataGrid.Items[currentDataGridSelectionIndex]);
                if (drv != null)
                {
                    DataTableWrapper dtw = curContainer.GetDataTableWrapper(curDataViewIndex);
                    if (dtw == null)
                    {
                        drv.CancelEdit();
                        return;
                    }
                    curContainer.GetDataTableWrapper(curDataViewIndex).Change(currentDataGridSelectionIndex, drv.Row);
                    drv.EndEdit();
                }
            }
        }

        private void OnDataGridCellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
        {
        }

        private void OnDataGridBeginningEdit(object sender, DataGridBeginningEditEventArgs e)
        {
            // TODO: 用作历史记录
            if (currentDataGridSelectionIndex != -1)
            {
                DataRowView drv = (DataRowView)(dataGrid.Items[currentDataGridSelectionIndex]);
                drv.BeginEdit();
            }
        }

        // check box 相关功能
        private void CbTableEdiableHandleCheck(object sender, RoutedEventArgs e)
        {
            dataGrid.IsReadOnly = true;
        }

        private void CbTableEdiableHandleUnCheck(object sender, RoutedEventArgs e)
        {
            dataGrid.IsReadOnly = false;
        }
        #endregion

        #region ContextMenu
        private void OnDataGridCmOpening(object sender, ContextMenuEventArgs e)
        {
            // 抽取当前所在的行
        }

        private void DataGridCmUpInsert(object sender, RoutedEventArgs e)
        {
            curContainer.GetDataTableWrapper(curDataViewIndex).InsertAt(dataGrid.SelectedIndex);
        }

        private void DataGridCmDownInsert(object sender, RoutedEventArgs e)
        {

            curContainer.GetDataTableWrapper(curDataViewIndex).InsertAt(dataGrid.SelectedIndex + 1);
        }

        private void DataGridCmDeleteRow(object sender, RoutedEventArgs e)
        {
            int[] indexes = GetSelectedRowsIndex();
            foreach (int i in indexes)
            {
                curContainer.GetDataTableWrapper(curDataViewIndex).Delete(i);
            }
        }

        private void DataGridCmMoveUp(object sender, RoutedEventArgs e)
        {
            curContainer.GetDataTableWrapper(curDataViewIndex).Move(dataGrid.SelectedIndex, -1);
        }

        private void DataGridCmMoveDown(object sender, RoutedEventArgs e)
        {
            curContainer.GetDataTableWrapper(curDataViewIndex).Move(dataGrid.SelectedIndex, 1);
        }

        private void DataGridCmSwap(object sender, RoutedEventArgs e)
        {
            if (dataGrid.SelectedItems.Count != 2)
            {
                // TODO: log
                throw new System.Exception("Must choose TWO rows to perform swap");
            }

            int[] indexes = GetSelectedRowsIndex();

            curContainer.GetDataTableWrapper(curDataViewIndex).Swap(indexes[0], indexes[1]);
        }
        #endregion

        #region Other Help functions
        private int[] GetSelectedRowsIndex()
        {
            int[] indexes = new int[dataGrid.SelectedItems.Count];

            DataRowView[] drvs = new DataRowView[dataGrid.SelectedItems.Count];
            for (int i = 0; i < dataGrid.SelectedItems.Count; i++)
            {
                drvs[i] = (System.Data.DataRowView)dataGrid.SelectedItems[i];

                indexes[i] = curContainer.GetDataTableWrapper(curDataViewIndex).GetIndexFromCurrentDataView(drvs[i]);
            }

            return indexes;
        }

        private void AreButtonsAvailable()
        {
            DataTableWrapper dtw = curContainer.GetDataTableWrapper(curDataViewIndex);

            if (dataGrid.SelectedItems.Count == 1 )
            {
                CM_upInsert.IsEnabled = true;
            }
            else
            {
                CM_upInsert.IsEnabled = false;
            }

            if (dataGrid.SelectedItems.Count == 1 )
            {
                CM_downInsert.IsEnabled = true;
            }
            else
            {
                CM_downInsert.IsEnabled = false;
            }

            if (dataGrid.SelectedItems.Count == 1 && dataGrid.SelectedIndex != dtw.InnerTable.Count - 1)
            {
                CM_moveDown.IsEnabled = true;
            }
            else
            {
                CM_moveDown.IsEnabled = false;
            }

            if (dataGrid.SelectedItems.Count == 1 && dataGrid.SelectedIndex != 0)
            {
                CM_moveUp.IsEnabled = true;
            }
            else
            {
                CM_moveUp.IsEnabled = false;
            }

            if (dataGrid.SelectedItems.Count != 2)
            {
                CM_swap.IsEnabled = false;
            }
            else
            {
                CM_swap.IsEnabled = true;
            }
        }
        #endregion


        private void OnDataGridAutoGeneratingColumn(
                    object sender, DataGridAutoGeneratingColumnEventArgs e)
        {
            FileTranslator.ForeignKeyConstraint fkc;
            ColumnProperty columnProperty = curContainer.CheckColumnProperty(e.PropertyName, out fkc);
            DataTableWrapper dtw = curContainer.GetDataTableWrapper(curDataViewIndex);

            if (dtw == null)
            {
                return;
            }

            if (columnProperty == ColumnProperty.FOREIGN_KEY)
            {
                // 定制ComboBox
                DataGridTemplateColumn column = new DataGridTemplateColumn();
                column.Header = e.PropertyName;

                // 设置Editing mode
                DataTemplate datatemplate = new DataTemplate();
                FrameworkElementFactory fef = new FrameworkElementFactory(typeof(ComboBox));
                Binding binding = new Binding();
                binding.Source = fkc.ReferenceTable.DefaultView;
                binding.Converter = new ComboBoxConverter(); // 每生成一次ComboBox下的list只会被调用一次
                binding.ConverterParameter = fkc;
                fef.SetBinding(ComboBox.ItemsSourceProperty, binding);
                Binding selectVal = new Binding(e.PropertyName);
                selectVal.Mode = BindingMode.TwoWay;
                fef.SetBinding(ComboBox.SelectedValueProperty, selectVal);

                fef.AddHandler(ComboBox.SelectionChangedEvent,
                    (SelectionChangedEventHandler)delegate(object sender2, SelectionChangedEventArgs e2)
                    {
                        ComboBox cb = sender2 as ComboBox;

                        if (cb != null && cb.SelectedIndex != -1)
                        {
                            // 原来因为为了修正DataGrid的一个bug而将所有的“_”转换为“__”,所以先转换回来
                            string columnName = ((string)column.Header).Replace("__", "_");

                            dtw.InnerTable[currentDataGridSelectionIndex][columnName]
                                = fkc.ReferenceTable.Rows[cb.SelectedIndex][fkc.OtherTablePrimaryKeyColumnName].ToString();

                            // 由CellEditEnding来做验证测试
                        }
                    });

                fef.SetValue(ComboBox.SelectedValuePathProperty, fkc.OtherTablePrimaryKeyColumnName);

                datatemplate.VisualTree = fef;
                column.CellEditingTemplate = datatemplate;

                // 设置显示时的mode
                datatemplate = new DataTemplate();
                fef = new FrameworkElementFactory(typeof(Label));

                binding = new Binding(e.PropertyName);
                selectVal.Mode = BindingMode.TwoWay;
                fef.SetBinding(Label.ContentProperty, binding);

                datatemplate.VisualTree = fef;
                column.CellTemplate = datatemplate;

                // 设定列
                e.Column = column;
            }

            if (columnProperty == ColumnProperty.READONLY)
            {
                e.Column.IsReadOnly = true;
            }

            // 修正DataGrid的一个bug，即单个“_”可能会显示不出来
            e.Column.Header = ((string)e.Column.Header).Replace("_", "__");
        }

        private void OnDataGridInitializingNewItem(object sender, InitializingNewItemEventArgs e)
        {
        }

        #endregion

        #region Property Grid
        private void NotifyPropertyGridSelectedChanged(int index)
        {
            DataTableWrapper dtw = curContainer.GetDataTableWrapper(curDataViewIndex);
            if (dtw == null)
            {
                return;
            }
            DataRowForPropGrid propGridRow = dtw.GetDataRowForPropGridUse(index);
            this.PropertyEditingGrid.SelectedObject = propGridRow;
        }
        #endregion

        #region Printing Related Functions
        private void OnPrintingViewInitialized(object sender, EventArgs e)
        {
            DataTable dt = new DataTable("test");

            // first of all, manually create a DataTable
            dt.Columns.Add(new DataColumn("id", typeof(int)));
            dt.Columns.Add(new DataColumn("name", typeof(string)));
            dt.Columns.Add(new DataColumn("测试", typeof(string)));

            // insert lines
            DataRow dr = dt.NewRow();
            dr["id"] = 1;
            dr["name"] = "BB1";
            dr["测试"] = "测试1";
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr["id"] = 2;
            dr["name"] = "BB2";
            dr["测试"] = "测试2";
            dt.Rows.Add(dr);

            dr = dt.NewRow();
            dr["id"] = 3;
            dr["name"] = "BB3";
            dr["测试"] = "测试3";
            dt.Rows.Add(dr);

            DataGrid dg = new DataGrid();
            dg.ItemsSource = dt.DefaultView;

            FixedDocument fix = new FixedDocument();
            PageContent pc = new PageContent();
            FixedPage fp = new FixedPage();
            fp.Width = fix.DocumentPaginator.PageSize.Width;
                fp.Height = fix.DocumentPaginator.PageSize.Height;

                fp.Children.Add(dg);
                ((System.Windows.Markup.IAddChild)pc).AddChild(fp);

                fix.Pages.Add(pc);
                docViewer.Document = fix;
            
        }
        #endregion

        #region Table Switch Related Functions
        private void OnFmtDefineButClick(object sender, RoutedEventArgs e)
        {
            ResetIndexes();
            
            curContainer = LoaderHelper.GetFmtData();
            ResetUi();
        }

        private void ResetIndexes()
        {
            curDataViewIndex = 0;
            currentDataGridSelectionIndex = 0;
        }

        private void OnFldDefineButClick(object sender, RoutedEventArgs e)
        {
            ResetIndexes();
            curContainer = LoaderHelper.GetFldData();
            ResetUi();

            // 非管理员不能进行编辑
            dataGrid.IsReadOnly = true;
        }

        private void OnFldProcessorDefineButClick(object sender, RoutedEventArgs e)
        {
            ResetIndexes();
            curContainer = LoaderHelper.GetFldProcData();
            ResetUi();
        }

        private void ResetUi()
        {
            // 清空TreeView
            this.FileListTreeView.Items.Clear();
            OnTreeViewInitialized(this, null);
            OnTreeViewLoaded(this, null);

            // 重置DataGrid
            OnDataGridLoaded(this, null);
        }
        #endregion

    }
}
